package cn.pconline.autoclub.service;

import cn.pconline.autoclub.util.Pager;
import cn.pconline.autoclub.util.StringUtil;
import org.gelivable.dao.GeliDao;
import org.gelivable.dao.SqlBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;

/**
 *
 * @author chenchongqi
 */
public class PagerService {

    private static final Logger log = LoggerFactory.getLogger(PagerService.class);
    @Autowired
    protected GeliDao geliDao;

    public <T> Pager<T> pager(Class<T> type, SqlBuilder sqlBuilder, int pageNo, int pageSize) {
        Pager<T> pager = new Pager<T>();
        pager.setPageNo(pageNo);
        pager.setPageSize(pageSize);
        pager.setTotal(count(sqlBuilder));
        if (pageNo < 0 || pageNo > pager.getPageCount() || isPageOutRange(pageNo, pageSize)) {
            throw new Pager.IllegalPageException("非法页码: " + pageNo);
        }
        try {
            pager.setResultList(geliDao.page(type, sqlBuilder.getSql(), pageNo, pageSize, sqlBuilder.getValues()));
        } catch (EmptyResultDataAccessException e) {
            log.warn("empty result!sql:{} values:{},pageNo:{},pageSize:{}",
                    sqlBuilder.getSql(), StringUtil.toString(sqlBuilder.getValues()),pageNo,pageSize);
        }
        return pager;
    }
    
    public <T> Pager<T> pagerWithOutList(Class<T> type, SqlBuilder sqlBuilder, int pageNo, int pageSize) {
        Pager<T> pager = new Pager<T>();
        pager.setPageNo(pageNo);
        pager.setPageSize(pageSize);
        pager.setTotal(count(sqlBuilder));
        if (pageNo < 0 || pageNo > pager.getPageCount() || isPageOutRange(pageNo, pageSize)) {
            throw new Pager.IllegalPageException("非法页码: " + pageNo);
        }
        return pager;
    }

    public <T> Pager<T> pager(Class<T> type, long x, SqlBuilder sqlBuilder, int pageNo, int pageSize) {
        Pager<T> pager = new Pager<T>();
        pager.setPageNo(pageNo);
        pager.setPageSize(pageSize);
        pager.setTotal(count(sqlBuilder));
        if (pageNo < 0 || pageNo > pager.getPageCount() || isPageOutRange(pageNo, pageSize)) {
            throw new Pager.IllegalPageException("非法页码: " + pageNo);
        }
        try {
            pager.setResultList(geliDao.page(type, x, sqlBuilder.getSql(), pageNo, pageSize, sqlBuilder.getValues()));
        } catch (EmptyResultDataAccessException e) {
        }
        return pager;
    }

    private int count(SqlBuilder sqlBuilder) {
        String sql = sqlBuilder.getSql();
        String countSql = sql.replace(sql.substring(0, sql.toLowerCase().indexOf("from")), "select count(1) ");
        int orderIndex = countSql.toLowerCase().lastIndexOf("order by");
        if(orderIndex>0){
            countSql = countSql.substring(0, orderIndex);
        }
        return geliDao.count(countSql, sqlBuilder.getValues());
    }

    private boolean isPageOutRange(int pageNo, int pageSize) {
        int offset = (pageNo - 1) * pageSize;
        if (offset < 0 || offset > Integer.MAX_VALUE) {
            return true;
        }
        return false;
    }
}
